package com.resource.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.resource.configuration.http.HttpClientUtils;
import com.resource.constant.OfficeApiConstants;
import com.resource.converter.ProjectTaskConverter;
import com.resource.dto.OfficeProjectInfoDto;
import com.resource.dto.OfficeProjectTaskDto;
import com.resource.query.ProjectQuery;
import com.resource.request.OfficeProjectTaskRequest;
import com.resource.response.OfficeResponse;
import com.resource.service.OfficeProjectService;
import com.resource.service.OfficeProjectTaskService;

import com.resource.utils.HttpUtils;
import com.resource.utils.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * 泛微项目任务服务实现类
 *
 * @author jianghao.zhang
 */
@Slf4j
@Service
public class OfficeProjectTaskServiceImpl implements OfficeProjectTaskService {

    @Resource
    private ProjectTaskConverter projectTaskConverter;

    @Value("${office.api.url}")
    private String apiUrl;

    @Value("${office.app.user}")
    private String user;

    @Resource
    private OfficeProjectService officeProjectService;

    private static ThreadLocal<DateFormat> threadLocal = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));

    /**
     * 项目创建任务
     *
     * @param request 项目任务信息
     */
    @Override
    public void addProjectTask(OfficeProjectTaskRequest request) throws ServiceException {
        OfficeProjectTaskDto dto = projectTaskConverter.requestToDto(request);

        // 通过holdCode查询项目列表（可能存在一个企业编号对应多个项目的情况）
        ProjectQuery query = new ProjectQuery();
        // TODO 区分寄售和网络货运吗？
        query.setManager_type("2");
        query.setField_3(request.getHoldCode());
        List<OfficeProjectInfoDto> list = officeProjectService.getProjectList(query);
        if (CollectionUtil.isEmpty(list)) {
            throw new ServiceException("根据平台账号未找到对应项目信息");
        }

        // 根据项目创建时间倒序排序
        list.sort((OfficeProjectInfoDto a, OfficeProjectInfoDto b) -> {
            try {
                Date createTimeA = threadLocal.get().parse(a.getCreatedAt());
                Date createTimeB = threadLocal.get().parse(b.getCreatedAt());
                return -DateUtil.compare(createTimeA, createTimeB);
            } catch (ParseException e) {
                throw new ServiceException("解析项目创建时间失败：", e.getCause());
            }
        });

        // 查询企业所有项目中最新一个项目的详情
        OfficeProjectInfoDto projectDetail = officeProjectService.getProjectInfoById(list.get(0).getDataId());

        // 若任务类型为"项目预警"，则自动选取项目的创建人作为执行人和创建人
        if ("0".equals(request.getType())) {
            dto.setTask_persondo(projectDetail.getManagerPerson());
            dto.setTask_creater(projectDetail.getManagerPerson());
        } else {
            // 若任务类型为"常规任务"，则接受给定的人员id作为执行人和创建人
            if (StringUtils.isEmpty(request.getExecutor())) {
                throw new ServiceException("任务执行人必填");
            }
            dto.setTask_persondo(request.getExecutor());
            dto.setTask_creater(request.getExecutor());
        }

        dto.setTask_project(String.valueOf(projectDetail.getDataId()));
        Date beginTime = DateUtil.parse(request.getBeginDate(), DatePattern.NORM_DATE_PATTERN);
        Date endTime = DateUtil.parse(request.getEndDate(), DatePattern.NORM_DATE_PATTERN);
        long btwDays = DateUtil.betweenDay(beginTime, endTime, true) + 1;
        dto.setWorking_days((int) btwDays);
        dto.setTask_level(1);
        dto.setTask_explain("<p>" + dto.getTask_explain() + "</p>");
        dto.setTask_remark("<p>" + dto.getTask_remark() + "</p>");
        dto.setCreat_time(threadLocal.get().format(new Date()));

        // 新增项目任务
        HttpEntity<String> req = HttpUtils.setHttpEntity(HttpMethod.POST, JSONUtil.toJsonStr(dto), user);
        log.info("【project task】addProjectTask request : {}", JSONUtil.toJsonStr(req));
        try {
            ResponseEntity<OfficeResponse<Object>> resp = HttpClientUtils.getClient().exchange(apiUrl + OfficeApiConstants.PROJECT_TASK_ADD,
                    HttpMethod.POST, req, new ParameterizedTypeReference<OfficeResponse<Object>>() {
                    });
            log.info("【project task】addProjectTask response：{}", JSONUtil.toJsonStr(resp));
            if (!ObjectUtil.equal(resp.getStatusCode(), HttpStatus.OK)
                    || resp.getBody() == null
                    || resp.getBody().getStatus() != OfficeApiConstants.SUCCESS) {
                throw new ServiceException("新增项目任务失败：" + JSONUtil.toJsonStr(resp));
            }
        } catch (Exception e) {
            log.error("新增项目任务失败，出现异常：", e.getCause());
            throw new ServiceException("新增项目任务失败，出现异常：", e.getCause());
        }
    }

}
